/*
Gin 框架

http://127.0.0.1:8080/users
http://127.0.0.1:8080/user/1

http://127.0.0.1:8080/login/jasper
http://127.0.0.1:8080/curUser
*/
package main

import (
	"context"
	"errors"
	"github.com/gin-gonic/gin"
)

type User struct {
	ID   uint64
	Name string
}

const COOKIE_USER = "zxy"

type keyType struct{}

var ctxKey = keyType{}

var users = []User{{ID: 123, Name: "张三"}, {ID: 456, Name: "李四"}}

func main() {
	engine := gin.Default()

	engine.Use(middleware())

	regRouter(engine)

	engine.Run(":8080")
}

func regRouter(engine *gin.Engine) {
	engine.GET("/users", listUsers)
	engine.GET("/user/:id", getUser)
	engine.GET("/login/:name", login)
	engine.GET("/curUser", getCurUser)
}

func middleware() gin.HandlerFunc {
	// cookie有登录态的话就放入 ctx 中
	return func(c *gin.Context) {
		req := c.Request
		cookie, err := req.Cookie(COOKIE_USER)
		if err != nil {
			c.Next()
			return
		}

		loginUser := User{ID: 100, Name: cookie.Value}
		ctx := context.WithValue(req.Context(), ctxKey, loginUser)
		c.Request = req.WithContext(ctx)
		c.Next()
	}
}

func listUsers(c *gin.Context) {
	c.JSON(200, users)
}

func getUser(c *gin.Context) {
	id := c.Param("id")
	c.String(200, "The user id is  %s", id)
}

func login(c *gin.Context) {
	name := c.Param("name")
	c.SetCookie(COOKIE_USER, name, 60, "/", "127.0.0.1", false, true)
	c.String(200, "login success")
}

func getCurUser(c *gin.Context) {
	user, _ := getUserFromCtx(c.Request.Context())
	c.JSON(200, user)
}

func getUserFromCtx(ctx context.Context) (User, error) {
	if user, ok := ctx.Value(ctxKey).(User); ok {
		return user, nil
	} else {
		return user, errors.New("user not found")
	}
}
